#include "page_handler.h"

struct _cef_life_span_handler_t *CEF_CALLBACK get_life_span_handler(struct _cef_client_t *self) {
    // DEBUG_CALLBACK("log:   get_life_span_handler\n");
    // Implemented!
    size_t offset = offsetof(page_handler, cef_client);
    page_handler *page = (page_handler *)((char *)self - offset);

    return &page->cef_life_span_handler;
}

struct _cef_drag_handler_t* CEF_CALLBACK get_drag_handler(struct _cef_client_t* self) {
    LOG_DEBUG("start get_drag_handler");
    size_t offset = offsetof(page_handler, cef_client);
    page_handler *page = (page_handler *)((char *)self - offset);

    return &page->cef_drag_handler;
}

void CEF_CALLBACK on_after_created(struct _cef_life_span_handler_t *self, struct _cef_browser_t *browser) {
    page_handler *page = (page_handler *)self;
    page->browser_size++;
    LOG_DEBUG("page->browser_size = %d", page->browser_size);
}

void CEF_CALLBACK on_before_close(struct _cef_life_span_handler_t *self, struct _cef_browser_t *browser) {
    page_handler *page = (page_handler *)self;
    if (page->browser_size > 0) {
        page->browser_size--;
    }
    // LOG_DEBUG("browser base ref has_at_least_one_ref size:%d", browser->base.has_at_least_one_ref(&browser->base));
    // LOG_DEBUG("browser base ref size:%d", browser->base.has_one_ref(&browser->base));
    browser->base.release(&browser->base);
    
    int size = page->browser_size;
    LOG_DEBUG("page->browser_size = %d", size);
    if (size == 0) {
        cef_quit_message_loop();
        LOG_INFO("cef_quit_message_loop");
    }
}

int CEF_CALLBACK on_process_message_received(struct _cef_client_t *self, struct _cef_browser_t *browser,
                                             struct _cef_frame_t *frame, cef_process_id_t source_process,
                                             struct _cef_process_message_t *message) {
                                                
    return on_main_process_message_received(browser, frame, source_process, message);
}



void CEF_CALLBACK on_draggable_regions_changed(struct _cef_drag_handler_t *self, struct _cef_browser_t *browser,
                                                 struct _cef_frame_t *frame, size_t regionsCount,
                                                 cef_draggable_region_t const *regions) {
    cef_browser_view_t *browser_view = cef_browser_view_get_for_browser(browser);
    if (browser_view) {
        cef_window_t *window = browser_view->base.get_window(&browser_view->base);
        if (window) {
            window->set_draggable_regions(window, 1, regions);
        }
    }
}



// 初始化 window_delegate_t
page_handler *create_page_handler_t() {
    page_handler *page = (page_handler *)calloc(1, sizeof(page_handler));

    page->cef_life_span_handler.base.size = sizeof(cef_life_span_handler_t);
    page->cef_life_span_handler.on_after_created = on_after_created;
    page->cef_life_span_handler.on_before_close = on_before_close;

    page->cef_drag_handler.base.size = sizeof(cef_drag_handler_t);
    page->cef_drag_handler.on_draggable_regions_changed = on_draggable_regions_changed;

    page->cef_client.base.size = sizeof(cef_client_t);
    // page_handler_ref->cef_client.get_context_menu_handler = get_context_menu_handler;
    // page_handler_ref->cef_client.get_dialog_handler = get_dialog_handler;
    // page_handler_ref->cef_client.get_display_handler = get_display_handler;
    // page_handler_ref->cef_client.get_download_handler = get_download_handler;
    page->cef_client.get_drag_handler = get_drag_handler;
    // page_handler_ref->cef_client.get_focus_handler = get_focus_handler;
    // page_handler_ref->cef_client.get_jsdialog_handler = get_jsdialog_handler;
    // page_handler_ref->cef_client.get_keyboard_handler = get_keyboard_handler;
    page->cef_client.get_life_span_handler = get_life_span_handler; // Implemented!
    // page_handler_ref->cef_client.get_load_handler = get_load_handler;
    // page_handler_ref->cef_client.get_render_handler = get_render_handler;
    // page_handler_ref->cef_client.get_request_handler = get_request_handler;
    page->cef_client.on_process_message_received = on_process_message_received;
    page->browser_size = 0;

    return page;
}
